﻿using SuperKit.WindowForm.GalleryWindow;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Documents;
using System.Windows.Media.Imaging;
using static SuperKit.CommandReader;

namespace SuperKit
{

    public class GalleryBean : FileViewModelBase {
        // 这个东西是WINDOWS在4K分辨下对UI进行的缩放。也就是说，显示为100的图像，在4K分辨率下应该是150。
        public const float UI_RESIZE = 1.5f;
        public const int IMG_WIDTH = (int)(300 * UI_RESIZE);
        public const int IMG_HEIGHT = (int)(450 * UI_RESIZE);


        public string FullName { get; }
        public string Name { get; set; }
        public BitmapImage Pic { get; set; }
        public bool IsDiscard { get;  set; }

        public GalleryBean(string path) {
            FullName = path;
            Name = Path.GetFileName(path);
            IsDiscard = false;
        }

        public void LoadPic() {
            if (IsDiscard) {
                return;
            }
            var info = new FileInfo(FullName);
            if (info.Exists == false) {
                return;
            }


            if (Kit.IsFileType(info, Kit.EFFECT_IMG_EXTS) == false){
                Pic = GalleryLoader.GetPresetImage("File");
                OnPropertyChanged("Pic");
                return;
            }


            try {

                BitmapImage bit = new BitmapImage();
                using (FileStream fs = new FileStream(FullName, FileMode.Open)) {
                    fs.Seek(0, SeekOrigin.Begin);
                    int width = IMG_WIDTH;
                    int height = IMG_HEIGHT;


                    try {
                        var decoder = BitmapDecoder.Create(fs, BitmapCreateOptions.IgnoreColorProfile, BitmapCacheOption.OnLoad);
                        
                        var frame = decoder.Frames[0];
                        var width_rate = IMG_WIDTH / frame.Width;//原图的宽
                        var height_rate = IMG_HEIGHT / frame.Height;//原图的高
                        var rate = Math.Min(width_rate, height_rate);
                        width = (int)(frame.Width * rate);
                        height = (int)(frame.Height * rate);
                    } catch (FileFormatException ex) {

                    }
                    
                    bit.BeginInit();
                    bit.CreateOptions = BitmapCreateOptions.IgnoreColorProfile;
                    bit.CacheOption = BitmapCacheOption.OnLoad;
                    bit.DecodePixelWidth = width;//需要缩略图的解码宽度
                    bit.DecodePixelHeight = height;//缩略图的解码高度
                    bit.StreamSource = fs;
                    bit.EndInit();
                }

                Pic = bit;
                Pic.Freeze();
                OnPropertyChanged("Pic");
            } catch (Exception ex) {
               Name = ex.Message;
                OnPropertyChanged("Name");
            }
        }

    }

    public class GalleryLoaderPack {
        public List<GalleryBean> items;
        CancellationTokenSource canceller;

        public GalleryLoaderPack() {
            items = new List<GalleryBean>();
            canceller = new CancellationTokenSource();
        }

        public void Add(GalleryBean bean) {
            items.Add(bean);
        }

        public void Start() {
            if (items.Count == 0) {
                return;
            }
            Task.Factory.StartNew(Run, canceller.Token);
        }

        private void Run() {
            foreach (var item in items) {
                item.LoadPic();
            }
        }

        public void Cancel() {
            canceller.Cancel();
        }
    }

    public class GalleryLoader {
        public int THREAD = 5;

        private List<GalleryLoaderPack> packs;
        public string CurrentPath { get; private set; }
        public ObservableCollection<GalleryBean> Items { get; }


        public GalleryLoader(string path) {
            CurrentPath = path;
            Items = new ObservableCollection<GalleryBean>();
            packs = new List<GalleryLoaderPack>();
        }

        public ObservableCollection<GalleryBean> Load() {
            DirectoryInfo info = new DirectoryInfo(CurrentPath);
            var files = info.GetFiles();
            foreach (FileInfo file in files) {
                GalleryBean data = new GalleryBean(file.FullName);
                Items.Add(data);
            }

            // 将项目分割到线程中
            for (int i = 0; i < THREAD; i++) {
                packs.Add(new GalleryLoaderPack());
            }
            for (int i = 0; i < Items.Count; i++) {
                int index = i % THREAD;
                packs[index].Add(Items[i]);
            }

            // 开始异步加载
            foreach (var i in packs) {
                i.Start();
            }
            return Items;
        }

        public void Close() {
            foreach (var i in packs) {
                i.Cancel();
            }
        }

        public void RemoveDiscard() {
            for (int i = Items.Count - 1; i >= 0; i--) {
                GalleryBean data = Items[i];
                if (data.IsDiscard) {
                    Items.RemoveAt(i);
                    continue;
                }
            }
        }

        private static Dictionary<string, BitmapImage> PresetImages = new Dictionary<string, BitmapImage>();

        public static BitmapImage GetPresetImage(string key) {
            if (PresetImages.ContainsKey(key)) {
                return PresetImages[key];
            }
            BitmapImage img;
            if (Kit.IsEqual("Checked", key)) {
                img = LoadSystemImage("ic_checkedc");
            } else if (Kit.IsEqual("File", key)) {
                img = LoadSystemImage("ic_file");
            } else if (Kit.IsEqual("Folder", key)) {
                img = LoadSystemImage("ic_folder");
            } else {
                img = LoadSystemImage("ic_xc");
            }

            PresetImages[key] = img;
            return img;
        }

        private static BitmapImage LoadSystemImage(string name) {
            var bmp = new BitmapImage(new Uri($"pack://application:,,,/SuperKit;component/Images/{name}.png"));
            bmp.Freeze();
            return bmp;
        }

    }
}
